<?php
//定义Sphinx目录物理路径
define ( 'SphinxRoot', dirname ( __FILE__ ) );
class SphinxAPI {
	protected static $_instance = NULL;
	private $option = array ();
	private $Sphinx;
	public static function getInstance() 
        {
      		if( self::$_instance === NULL ) {
        		self::$_instance = new SphinxAPI();
      		}
      		return self::$_instance;
    	}	
	public function __construct($options = NULL) {
		$option = $this->__Config ( $options );
		if (is_array ( $option )) {
			$this->option ['host'] = ($option ['host'] ? $option ['host'] : 'localhost');
			$this->option ['port'] = ($option ['port'] ? $option ['port'] : 3302);
			$this->option ['match_mode'] = ($option ['match_mode'] ? $option ['match_mode'] : '');
			require_once SphinxRoot . '/sphinxapi.php';
			$this->Sphinx = new SphinxClient ();
			$Sphinx_host = $this->option ['host'];
			$Sphinx_port = $this->option ['port'];
			$this->Sphinx->SetServer ( $Sphinx_host, $Sphinx_port );
			$this->Sphinx->SetConnectTimeout ( 5 );
			$this->Sphinx->SetArrayResult ( true );
			
			return $this;
		}
	}
	public function __destruct() {
		unset($this->Sphinx);
		unset ( $this );
	}
	public function __Config($option = null) {
		if ($option)
			return $option;
		else
			return array();
	}
	public function Query($keywords, $index, $options = array()) {
		// initialize the options
		$defaults = array ('limit' => 10, 'offset' => 0, 'sort' => array (), 'filters' => array (), 'match_mode' => '', 'groupby' => array (), 'comment' => '' );
		foreach ( $defaults as $k => $v ) {
			$options [$k] = array_key_exists ( $k, $options ) ? $options [$k] : $v;
		}
		if ($options ['match_mode']) {
			$this->Sphinx->SetMatchMode ( $options ['match_mode'] );
		}
		
		if ($options ['sort'] && is_array ( $options ['sort'] )) {
			$Sort_Mode = $options ['sort'] ['direction'] == 'DESC' ? SPH_SORT_ATTR_DESC : SPH_SORT_ATTR_ASC;
			$this->Sphinx->SetSortMode ( $Sort_Mode, $options ['sort'] ['field'] );
		}
		if ($options ['groupby'] && is_array ( $options ['groupby'] )) {
			$func = $options ['groupby'] ['func'] ? $options ['groupby'] ['func'] : SPH_GROUPBY_ATTR;
			$groupsort = $options ['groupby'] ['groupsort'] ? $options ['groupby'] ['groupsort'] : '@count desc';
			$this->Sphinx->SetGroupBy ( $options ['groupby'] ['field'], $func, $groupsort );
			$offset = 0;
			$limit = $options ['groupby'] ['limit'] ? $options ['groupby'] ['limit'] : 1000;
			$this->Sphinx->SetLimits ( $offset, $limit );
			$this->Sphinx->AddQuery ( $keywords, $index, $options ['comment'] );
			$this->Sphinx->ResetGroupBy ();
			if ($options ['filters'] && is_array ( $options ['filters'] )) {
				foreach ( $options ['filters'] as $key => $value ) {
					$this->Sphinx->SetFilter ( $key, $value );
				}
			}
			$this->Sphinx->SetLimits ( $options ['offset'], $options ['limit'] );
			$this->Sphinx->AddQuery ( $keywords, $index, $options ['comment'] );
			$result = $this->Sphinx->RunQueries ();
		} else {
			if ($options ['filters'] && is_array ( $options ['filters'] )) {
				foreach ( $options ['filters'] as $key => $value ) {
					$this->Sphinx->SetFilter ( $key, $value );
				}
			}
			$this->Sphinx->SetLimits ( $options ['offset'], $options ['limit'] );
			$result = $this->Sphinx->Query ( $keywords, $index, $options ['comment'] );
		}
		if (! $result) {
			$Data ['Status'] = 'Error';
			$Data ['ErrorMessage'] = $ErrorMessage = 'Ooops!You Have an Error In Your Sphinx Query : "' . $this->Sphinx->GetLastError () . '"';
			return $Data;
		}
		if ($options ['groupby']) {
			$GroupResult = $result [0];
			$ListResult = $result [1];
			$Data ['GroupList'] = $this->GetGroupListByResult ( $GroupResult );
		} else {
			$ListResult = $result;
		}
		$Data ['IDList'] = $this->GetIDListByResult ( $ListResult );
		$Data ['TotalCount'] = $this->GetTotalCount ( $ListResult );
		$Data ['Keywords'] = $this->GetKeyWords ( $ListResult );
		return $Data;
	}
	public static function GetIDListByResult($res) {
		if ($res ['matches']) {
			foreach ( $res ['matches'] as $Result ) {
				$id [] = $Result ['id'];
			}
			$idlist = implode ( ',', $id );
		}
		return $idlist;
	}
	public static function GetGroupListByResult($res) {
		if ($res ['matches']) {
			foreach ( $res ['matches'] as $Result ) {
				$Group = $Result ['attrs'] ['@groupby'];
				$GroupList [$Group] = $Result ['attrs'] ['@count'];
			}
		}
		return $GroupList;
	}
	public static function GetKeyWords($res) {
		if ($res ['words']) {
			foreach ( $res ['words'] as $key=>$Result ) {
				$KeywordsList [] = $key;
			}
		}
		return $KeywordsList;
	}
	public static function GetTotalCount($res) {
		return $res ['total_found'];
	}
	public function SetFilter($key, $value) {
		$this->Sphinx->SetFilter ( $key, $value );
	}
}
?>
